package com.joysuch.wwyt.datadump.biz.processor;

import cn.hutool.core.lang.Assert;
import cn.zlg.common.datadump.annotation.DataDumpEntity;
import cn.zlg.common.datadump.processor.BaseImportEntityProcessor;
import com.joysuch.wwyt.common.entity.CommonType;
import com.joysuch.wwyt.common.enums.CommonTypes;
import com.joysuch.wwyt.common.repository.CommonTypeDao;
import com.joysuch.wwyt.common.service.CommonTypeService;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.datadump.biz.model.EduQuestionDumpBean;
import com.joysuch.wwyt.datadump.biz.model.MhMajorHazardChemProductRelBean;
import com.joysuch.wwyt.datadump.biz.model.MhMajorHazardDumpBean;
import com.joysuch.wwyt.edu.entity.EduQuestion;
import com.joysuch.wwyt.edu.entity.EduQuestionItem;
import com.joysuch.wwyt.edu.enums.QuestionTypes;
import com.joysuch.wwyt.edu.repository.EduQuestionDao;
import com.joysuch.wwyt.edu.repository.EduQuestionItemDao;
import com.joysuch.wwyt.edu.repository.EduTestPaperQuestionDao;
import com.joysuch.wwyt.mh.entity.MhMajorHazard;
import com.joysuch.wwyt.mh.entity.MhMajorHazardChemProduct;
import com.joysuch.wwyt.mh.entity.MhMajorHazardChemProductRel;
import com.joysuch.wwyt.mh.repository.MhMajorHazardChemProductDao;
import com.joysuch.wwyt.mh.repository.MhMajorHazardChemProductRelDao;
import org.apache.tomcat.util.buf.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;

@Component
public class EduQuestionImportProcessor extends BaseImportEntityProcessor<EduQuestionDumpBean, EduQuestion> {

    private static final Logger logger = LoggerFactory.getLogger(EduQuestionImportProcessor.class);

    @Autowired
    private EduQuestionItemDao questionItemDao;
    @Autowired
    private EduQuestionDao eduQuestionDao;
    @Autowired
    private EduTestPaperQuestionDao eduTestPaperQuestionDao;
    @Autowired
    private CommonTypeDao commonTypeDao;
    @Autowired
    private CommonTypeService commonTypeService;
    @Autowired
    private BaseUserDao baseUserDao;

    @Override
    public EduQuestionDumpBean processAftertValidate(EduQuestionDumpBean origin, DataDumpEntity annotation) {
        EduQuestion content = eduQuestionDao.selectByCode(origin.getCode());
        String code = QuestionTypes.findByName(origin.getType()).getCode();
        if (content != null && !code.equals(content.getType())) {
            int count = eduTestPaperQuestionDao.countByQuestionId(content.getId());
            if (count > 0) {
                throw new IllegalArgumentException("该试题已成为考试试题不能修改类型");
            }
        }
        CommonType type = commonTypeDao.findQuestionTypeName(origin.getQuestionTypeName());
        if (type == null) {
            CommonType commonType = new CommonType();
            commonType.setName(origin.getQuestionTypeName());
            commonType.setType(CommonTypes.QUESTION.getName());
            commonType.setObjCount(0);
            commonTypeDao.save(commonType);
        }
        return origin;
    }


    @Override
    public EduQuestion processBeforeSave(EduQuestionDumpBean origin, EduQuestion entity, DataDumpEntity annotation) {

        entity.setCreateUserName(baseUserDao.getBaseUserNameById(Context.getCurrentUserId()));
        List<EduQuestionItem> items = getEduQuestionItems(origin, entity);
        validateAnswerCorrection(origin.getAnswer(), entity.getType(), items.size());
        return super.processBeforeSave(origin, entity, annotation);
    }

    @Override
    public EduQuestion processAfterSave(EduQuestionDumpBean origin, EduQuestion entity, DataDumpEntity annotation) {
        questionItemDao.deleteByQuestionId(entity.getId());
        if (!entity.getType().equals("Z")) {
            List<EduQuestionItem> items = getEduQuestionItems(origin, entity);
            questionItemDao.saveAll(items);
        }

        commonTypeService.updateTypeCount(CommonTypes.QUESTION, entity.getId());
        return entity;
    }

    private List<EduQuestionItem> getEduQuestionItems(EduQuestionDumpBean origin, EduQuestion entity) {
        List<EduQuestionItem> items = new ArrayList<>();

        if (QuestionTypes.JUDGE.is(entity.getType())) {
            if ("A".equals(origin.getAnswer()) || "是".equals(origin.getAnswer())) {
                entity.setAnswer("是");
            } else {
                entity.setAnswer("否");
            }
            items.add(createQuestionItem("是", entity.getId(), origin.getChoiceA(), 1));
            items.add(createQuestionItem("否", entity.getId(), origin.getChoiceB(), 2));
        } else {

            for (int i = 'A'; i <= 'Z'; i++) {
                String value = getFieldValue("choice" + ((char) i), origin);
                if (value == null || value.trim().length() == 0) {
                    // 遇到第一个空答案停止
                    break;
                } else {
                    items.add(createQuestionItem(String.valueOf((char) i), entity.getId(), value, i - 'A' + 1));
                }
            }
        }
        return items;
    }

    /**
     * 试题导入几个基本逻辑：
     * 1、答案用英文大写字母填写
     * 2、判断题，不用填选项，答案填写A,代表正确，填写B 代表错误；其他内容导入失败提示：x行答案填写错误
     * 3、多选题：多选答案用英文逗号分开，不区分顺序(A,B 和B,A是一样的）
     * 4、选择题，答案填写不在选项内，导入失败提示：x行答案填写错误（例如：只填写A\B选项内容，答案确填写C或其他）
     * <p>
     * 参考: http://zentao.seekcy.com:5555/zentao/bug-view-12262.html
     *
     * @param itemCount
     */
    private void validateAnswerCorrection(String an, String type, int itemCount) {
        if (QuestionTypes.JUDGE.is(type)) {
            Assert.isTrue("A".equals(an) || "B".equals(an), "判断题答案必须为A或B ");
        } else if (QuestionTypes.SINGLE.is(type)) {
            Assert.isTrue(an.length() == 1, "单选题答案只能有一个 ");
            char a = an.charAt(0);
            Assert.isTrue(a >= 'A' && a < 'A' + itemCount, "答案填写错误 ");
        } else if (QuestionTypes.MULTI_CHOICE.is(type)) {
            // 多选题
            String[] ss = an.split("\\s*,\\s*");
            Assert.isTrue(ss.length >= 1 && ss.length <= itemCount, "多选题答案至少一个，且不能超过选项个数 ");
            for (String s : ss) {
                Assert.isTrue(s.length() == 1, "多选题答案，不同答案之间需用【英文逗号】分隔 ");
                char a = s.charAt(0);
                Assert.isTrue(a >= 'A' && a < 'A' + itemCount, "多选题答案【" + s + "】不在范围内 ");
            }
            Set<String> set = new HashSet<>(Arrays.asList(ss));
            Assert.isTrue(ss.length == set.size(), "多选题答案【" + an + "】包含重复选项");
        }
    }

    private String getFieldValue(String s, EduQuestionDumpBean origin) {
        PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(EduQuestionDumpBean.class, s);
        if (pd != null && pd.getReadMethod() != null) {
            try {
                return (String) pd.getReadMethod().invoke(origin);
            } catch (Exception e) {
                logger.error("获取选项{}错误", s);
            }
        }
        return null;
    }

    private EduQuestionItem createQuestionItem(String choiceCode, Long id, String content, int i) {
        EduQuestionItem qi = new EduQuestionItem();
        qi.setChoiceCode(choiceCode);
        qi.setContent(content);
        qi.setIndexNo(i);
        qi.setQuestionId(id);
        return qi;
    }
}
